#include <iostream>
using std::cout;
using std::endl;

class Singleton {
    Singleton(int x,int y)
    : _ix(x)
    , _iy(y)
    {
        cout << "Singleton(int,int)" << endl;
    }

    ~Singleton(){
        cout << "~Singleton()" << endl;
    }

    //C++11之后的写法
    //表示从这个类中删除这个函数
    Singleton(const Singleton & rhs) = delete;
    Singleton & operator=(const Singleton& rhs) = delete;

public:
    static Singleton * getInstance(){
        if(_pInstance == nullptr){
            _pInstance  = new Singleton(1,2);
        }
        return _pInstance;
    }

    /* static void destroy(){ */
    /*     if(_pInstance){ */
    /*         delete _pInstance; */
    /*         _pInstance = nullptr; */
    /*     } */
    /*     cout << "delete heap" << endl; */
    /* } */

    void init(int x,int y){
        _ix = x;
        _iy = y;
    }

	void print()
	{
		cout << "(" << this->_ix 
            << "," << this->_iy
			<< ")" << endl;
	}
    friend class AutoRelease;
private:
	int _ix;
	int _iy;
    static Singleton * _pInstance;
};
Singleton * Singleton::_pInstance = nullptr;

class AutoRelease{
public:
    AutoRelease(Singleton * p)
    : _p(p)
    {
        cout << "AutoRelease(Singleton*)" << endl;
    }

    ~AutoRelease(){
        cout << "~AutoRelease()" << endl;
        if(_p){
            delete _p;
            _p = nullptr;
        }
    }

private:
    Singleton * _p;
};



void test0()
{
    AutoRelease ar(Singleton::getInstance());

    Singleton::getInstance()->init(100,200);
    Singleton::getInstance()->print();
    Singleton::getInstance()->print();
    Singleton::getInstance()->print();
    Singleton::getInstance()->print();

    //如果仍然手动调用destroy会造成double free
    //因为destroy函数的执行过程中利用_pInstance回收堆空间
    //ar对象在栈上，栈帧结束时销毁，必然会调用
    //AutoRelease的析构函数，仍然会尝试回收这片堆空间
    /* Singleton::destroy(); */
}

int main(void){
    test0();
    //如果局部对象ar生命周期结束了，堆上的单例对象也被回收
    //此时如果通过getInstance来访问这片空间，会访问到不确定的值
    /* Singleton::getInstance()->print(); */
    return 0;
}
